package com.navinfo.tripanalysis.service.impl;

import com.navinfo.tripanalysis.pojo.Point0200;
import com.navinfo.tripanalysis.pojo.Point;
import com.navinfo.tripanalysis.pojo.PreTripInfo;
import com.navinfo.tripanalysis.service.PreTripInfoService;
import com.navinfo.tripanalysis.util.CommonUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 东风行程切分
 * @author web
 */
public class PreTripInfoServiceImpl2 implements PreTripInfoService {
    /**
     * 精准切分速度阀值
     */
    private final int SPEED_THRESHOLD = 0;

    /**
     * 切分行程
     * 1）根据当天0200点，按发动机acc=on && 速度 > 0切分出子行程，统计出行程开始、结束时间及行程时长
     * 2）根据子行程的开始结束时间，切分出对应的0f37及0200的子数据
     * 3) 根据0200的子行程调用精准里程油耗算法算出子行程的精准里程、精准油耗
     * @param points0f37
     * @param points0200
     * @param day 当前日期
     * @return
     */
    public List<PreTripInfo> preJudgeTrip(List<Point> points0f37, List<Point0200> points0200, Date day) {
        List<PreTripInfo> list = new ArrayList<>();

        //只根据0200切分行程
        if (CommonUtils.isCollectionNotEmpty(points0200)) {
            PreTripInfo info = null;
            Long lastGpsTime = null;
            int tripId = 0;

            for (Point0200 pojo : points0200) {
                long gpsTime = pojo.getGpsTime();

                int status = judgeTripStatus(lastGpsTime, gpsTime, pojo);
                if (TRIP_START==status || TRIP_IN==status) {
                    if (info == null) {
                        info = new PreTripInfo();
                        info.setTripId(++tripId);
                        info.setStartTimeMs(pojo.getGpsTime());
                        info.setStartLongitude(pojo.getLongitude());
                        info.setStartLatitude(pojo.getLatitude());
                        info.setStartHeight((int)pojo.getHeight());
                        info.setStartDirection(pojo.getDirection());
                        info.setSubPoints0200(new ArrayList<>());
                    }
                    pojo.setTripId(info.getTripId());
                    info.getSubPoints0200().add(pojo);
                    lastGpsTime = gpsTime;
                } else {
                    if (info != null) {
                        pojo.setTripId(info.getTripId());
                        info.getSubPoints0200().add(pojo);
                        handleEnd(points0f37, list, info, status, day);
                    }
                    info = null;
                    lastGpsTime = null;
                }
            }

            handleEnd(points0f37, list, info,null, day);
        }

        return list;
    }

    /**
     * 判断行程状态
     * @param lastGpsTime 上一个point时间
     * @param gpsTime      当前point时间
     * @param point        0200点
     * @return
     */
    private int judgeTripStatus(Long lastGpsTime, long gpsTime, Point0200 point) {
        //行程未开始
        if (lastGpsTime == null) {
            //开始条件：acc=on && 速度 > 0
            return point.getAccStatus()==1 && point.getSpeedKmh()>SPEED_THRESHOLD ? TRIP_START : TRIP_NO_START;
        }
        //行程已开始
        else {
            if (isForceEnd(lastGpsTime, gpsTime)) {
                return TRIP_FORCE_END;
            } else {
                //结束条件：acc=off && 速度 = 0
                return point.getAccStatus()==0 && point.getSpeedKmh()==SPEED_THRESHOLD ? TRIP_END : TRIP_IN;
            }
        }
    }
}
